// Mark Czubin
#include "QtBoardCatalogusViewer.h"
#include <QGraphicsScene>
#include <QGraphicsItem>
#include <QDebug>

QtBoardCatalogusViewer::QtBoardCatalogusViewer(QWidget *parent) :
	QGraphicsView(parent)
{
	scene = new QGraphicsScene(this);

	scene->setBackgroundBrush(Qt::black);
	
	// some fancier background ...
	//	QLinearGradient gradient(QPointF(0,0),QPointF(2,2));
	//	gradient.setColorAt(0, Qt::yellow);
	//	gradient.setColorAt(1, Qt::white);
	//	gradient.setSpread(QGradient::ReflectSpread);	
	//	scene->setBackgroundBrush(gradient);
	
	setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
	setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
	scene->setSceneRect(110, -20, 380, 160);
	setScene(scene);
	
	rightTimer.setDuration(ANIMATION_SPEED);
	leftTimer.setDuration(ANIMATION_SPEED);
	rightTimer.setFrameRange(0, 100);
	leftTimer.setFrameRange(0, 100);

	// pad a number of elements, so there aren't any artifacts
	paddingSize = (NUM_ITEMS_VISIBLE - 1) / 2;
	
	// add previews and generate their animations
	createAnimations(NUM_ITEMS_VISIBLE);
	populateScene();
	
	position = 0;
}

QtBoardCatalogusViewer::~QtBoardCatalogusViewer()
{
	delete scene;
	//FIXME: delete whole other bunch as well...
}

void QtBoardCatalogusViewer::showNextEvent()
{
	//because I always expect the next button to shift the band to the left
	slideCatalogusLeft();
}

void QtBoardCatalogusViewer::showPreviousEvent()
{
	slideCatalogusRight();
}

bool QtBoardCatalogusViewer::slideCatalogusRight()
{
	if( ! (position > 0))
		return false;
	
	--position;
	qDebug() << "pos" << position;

	// hide the old item
	if(position + NUM_ITEMS_VISIBLE < previewImages.size())
		previewImages[position + NUM_ITEMS_VISIBLE]->hide();

	// shift all the items 1 position to the left
	for (int i = 0 ; i < NUM_ITEMS_VISIBLE ; ++i)
	{
		animationsToRight[i]->setItem(previewImages[position + i]);
		animationsToRight[i]->item()->show();
	}
	
	// start animation
	rightTimer.setDirection(QTimeLine::Forward);
	rightTimer.start();
	
	return true;
}

bool QtBoardCatalogusViewer::slideCatalogusLeft()
{	
	qDebug() << (position + paddingSize) ;
	qDebug() << previewImages.size();

	// IF NOT ()
	if( ! ((position + NUM_ITEMS_VISIBLE - 1) <  previewImages.size()))
		return false;
		
	// hide the old item
	if(position > 0)
		previewImages[position - 1]->hide();

	
	// shift all the items 1 position to the left
	for (int i = 0 ; i < NUM_ITEMS_VISIBLE ; ++i)
	{
		animationsToLeft[i]->setItem(previewImages[position + i]);
		animationsToLeft[i]->item()->show();
	}
	
	// start animation
	leftTimer.setDirection(QTimeLine::Forward);
	leftTimer.start();
	
	++position;
	
	return true;
}

// add some map previews to the screen.
void QtBoardCatalogusViewer::populateScene()
{
	QGraphicsItem * item;
	int l = -1;
	
	// ADD left padding
	for (int i = 0; i < paddingSize; ++i)
	{
		item = scene->addRect(QRectF(0,0,0,0));
		previewImages.append(item);
	}
	
	// ADD preview items
	for (int i = 0; i < NUM_ITEMS_VISIBLE; ++i)
	{	
		item = new QtMapPreviewItem(QString::number(++l));
		previewImages.append(item);
		scene->addItem(item);
	}
	
	// ADD right padding
	for (int i = 0; i < paddingSize; ++i)
	{
		item = scene->addRect(QRectF(0,0,0,0));
		previewImages.append(item);
	}
	
	for (int i = 0; i < NUM_ITEMS_VISIBLE; ++i)
		animationsToLeft[i]->setItem(previewImages[i]);
	
	for (int i = NUM_ITEMS_VISIBLE ; i < previewImages.size(); ++i)
		previewImages[i]->hide();
	
	for (int i = 0; i < NUM_ITEMS_VISIBLE; ++i)
		animationsToLeft[i]->setStep(0);
}

void QtBoardCatalogusViewer::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event);
}

void QtBoardCatalogusViewer::createAnimations(int number)
{	
	QGraphicsItemAnimation * animation;
	
	float scale_x_delta = TRANS_LENGTH / number;
	
	for(int num = 0 ; num < number ; ++num)
	{
		// first, creat a new animation
		animation = new QGraphicsItemAnimation;
		animation->setTimeLine(&leftTimer);
        	//nimation->setTranslationAt (0, 0.0, 0.0);
        	//animation->setTranslationAt (1, scale_x_delta, 0.0);
 	        animation->setPosAt (0, QPointF((scale_x_delta * (num + 1)), 0.0));
        	animation->setPosAt (1, QPointF((scale_x_delta * num), 0.0));   
		animationsToLeft.append(animation);
		
		animation = new QGraphicsItemAnimation;
		animation->setTimeLine(&rightTimer);
        	//animation->setTranslationAt (0, 0.0, 0.0);
        	//animation->setTranslationAt (1, -scale_x_delta, 0.0);
        	animation->setPosAt (0, QPointF((scale_x_delta * num), 0.0));
        	animation->setPosAt (1, QPointF((scale_x_delta * (num + 1)), 0.0));    
		animationsToRight.append(animation);
	}	
}

/*// old code, circular effect
void QtBoardCatalogusViewer::createAnimations(int number)
{	
	QGraphicsItemAnimation * animation;
	
	float scale_x_delta = 200.0 / number;
	float scale_x = -100;
	float scale_y;
	float scale_y_square;
	float scale_translation_x_offset;
	float scale_translation_y_offset;
	QPointF translation;
	
	for(int num = 0 ; num < number ; ++num)
	{
		// first, creat a new animation
		animation = new QGraphicsItemAnimation;
		animation->setTimeLine(&timer);
	        animations.append(animation);
		
		for(int j = 0 ; j <  scale_x_delta && scale_x <= 100; ++j )
		{	
	        	// create a half circle on the xy axis.
	        	// Y = 1 - X^2, normalized
	        	scale_y_square = (scale_x * scale_x) / (100.0 * 100.0);
	        	scale_y = 1.0 - scale_y_square;
	        	
	        	// keep the objects in the center when scaling
	        	scale_translation_x_offset = scale_y_square * 50.0;
	        	scale_translation_y_offset = scale_y_square * 60.0;

	        	// TODO: better to use, scale_y as translation (?)
	        	translation.setX(scale_translation_x_offset);// + (scale_x * 3));
	        	translation.setY(scale_translation_y_offset);
	        	
	        	// Set a circular scale, translation correction and movement
	        	animation->setScaleAt( (j/scale_x_delta), scale_y, scale_y);
        		animation->setPosAt  ( (j/scale_x_delta), translation);
			
			// go to next discrete evaluation point
	        	scale_x += 1.0;
	        }
	}
	
	// debug printouts
	// qDebug() << "SCALE" << num << j << (j/scale_x_delta) << scale_x << scale_y;
	// qDebug() << "SCALE OFFSET" << num << j << scale_translation_offset;
}*/

